home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CICA 1993 April
/
CICA MS Windows - April 1993.iso
/
unzipped
/
util
/
mews11
/
mswemacs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-26
|
17KB
|
530 lines
/* The routines in this file provide extra emacs functions available
under the Microsoft Windows environment on an IBM-PC or compatible
computer. The following functions are supplied: cutregion,
clipregion, insertclip and helpengine.
Also implemented here is the support for scroll bars
Must be compiled with Borland C++ 2.0 or MSC 6.0 or later versions
It should not be compiled if the WINDOW_MSWIN symbol is not set */
#include "estruct.h"
#include <stdio.h>
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#include "mswin.h"
#include "mswmenu.h"
/* to invoke the commands corresponding to scroll bar actions */
#define MAXSCROLL 32767 /* maximum position for scrollbars */
static HANDLE hClipData = NULL; /* used by insertclip and
ClipboardCleanup */
/* CopyToClipboard: internal function to copy region to clipboard */
/* =============== */
static BOOL PASCAL CopyToClipboard (REGION *Region)
{
long Size = 0L;
HANDLE hData;
#if WINDOW_MSWIN32
char *Data;
#else
char huge *Data;
#endif
BOOL Result = TRUE;
register LINE *lp;
register int Offset;
register int lcnt; /* used to reduce longop() overhead */
/*-figure out the size of the clipboard data (end of lines have to
be turned into CR-LF) */
Size = Region->r_size;
if (curwp->w_dotp != curwp->w_markp[0]) { /* multiple lines */
lp = Region->r_linep;
do {
++Size;
lp = lforw(lp);
} while ((lp != curwp->w_dotp) && (lp != curwp->w_markp[0]));
}
if (Size == 0L) return TRUE;
/*-copy the buffer data into a block of global memory */
if (hData = GlobalAlloc (GMEM_MOVEABLE, Size + 1)) {
if (!(Data = GlobalLock (hData))) goto NoClipboardMemory;
lp = Region->r_linep;
Offset = Region->r_offset;
lcnt = 0;
while (Size-- > 0) {
if (Offset != llength(lp)) { /* middle of line */
*Data++ = lgetc(lp, Offset);
++Offset;
}
else { /* end of line */
*Data++ = '\r';
*Data++ = '\n';
Size--;
lp = lforw(lp);
Offset = 0;
if (--lcnt < 0) {
longop (TRUE);
lcnt = 10; /* reduce longop calls overhead */
}
}
}
*Data = '\0';
/*-pass the text to the clipboard */
GlobalUnlock (hData);
if (OpenClipboard (hFrameWnd)) {
if (EmptyClipboard ()) {
SetClipboardData (CF_TEXT, hData);
}
else Result = FALSE;
CloseClipboard ();
}
else Result = FALSE;
if (Result == FALSE) GlobalFree (hData);
}
else {
NoClipboardMemory:
mlabort (TEXT94); /* out of memory */
Result = FALSE;
}
return Result;
} /* CopyToClipboard */
/* cutregion: move the current region to the clipboard */
/* ========= */
PASCAL cutregion (int f, int n)
{
REGION Region;
int Result;
/*-don't allow command if read-only mode */
if (curbp->b_mode & MDVIEW) return rdonly();
if ((Result = getregion (&Region)) != TRUE) return Result;
if ((Result = CopyToClipboard (&Region)) != TRUE) return Result;
curwp->w_dotp = Region.r_linep;
curwp->w_doto = Region.r_offset;
return ldelete (Region.r_size, FALSE);
} /* cutregion */
/* clipregion: copy the current region into the clipboard */
/* ========== */
PASCAL clipregion (int f, int n)
{
REGION Region;
int Result;
if ((Result = getregion (&Region)) != TRUE) return Result;
return CopyToClipboard (&Region);
} /* clipregion */
/* insertclip: insert the clipboard contents at dot */
/* ========== */
PASCAL insertclip (int f, int n)
{
BOOL Result = TRUE;
char *Text, *TextHead;
short int curoff;
LINE *curline;
/*-don't allow command if read-only mode */
if (curbp->b_mode & MDVIEW) return rdonly();
if (OpenClipboard (hFrameWnd)) {
if ((hClipData = GetClipboardData (CF_TEXT)) != NULL) {
/* Save the local pointers to hold global "." */
if (yankflag == SRBEGIN) {
/* Find the *previous* line, since the line we are on
may disappear due to re-allocation. This works even
if we are on the first line of the file. */
curline = lback(curwp->w_dotp);
curoff = curwp->w_doto;
}
if ((TextHead = GlobalLock (hClipData)) != NULL) {
while (n--) {
Text = TextHead;
while (*Text != '\0') {
if (*Text == '\n') {
if (lnewline () == FALSE) {
Result = FALSE;
goto bail_out;
}
}
else {
if (*Text != '\r') if (linsert (1, *Text) == FALSE) {
Result = FALSE;
goto bail_out;
}
}
++Text;
}
}
bail_out:
GlobalUnlock (hClipData);
hClipData = NULL; /* for ClipboardCleanup */
/* If requested, set global "." back to the beginning of
the yanked text. */
if (yankflag == SRBEGIN) {
curwp->w_dotp = lforw(curline);
curwp->w_doto = curoff;
}
}
}
else Result = FALSE;
CloseClipboard ();
}
else Result = FALSE;
return Result;
} /* insertclip */
/* ClipboardCleanup: to be called if the user aborts during a longop */
/* ================ */
void FAR PASCAL ClipboardCleanup (void)
{
if (hClipData) {
GlobalUnlock (hClipData);
CloseClipboard ();
}
} /* ClipboardCleanup */
/* helpengine: invoke the MS-Windows help engine */
/* ========== */
PASCAL helpengine (int f, int n)
{
char OldHelpFile [NFILEN];
char HelpKey [NLINE];
BOOL Result;
strcpy (OldHelpFile, HelpEngineFile);
SetWorkingDir ();
if ((Result = FILENAMEREPLY (TEXT307, HelpEngineFile, NFILEN)) != TRUE) return Result;
/* "Help file: " */
if (HelpEngineFile[0] == '\0') {
strcpy (HelpEngineFile, OldHelpFile);
return FALSE;
}
else {
Result = mlreply (TEXT308, HelpKey, NLINE);
if ((Result != TRUE) && (Result != FALSE)) return Result;
/* "Help key: " */
if (HelpKey[0] == '\0') {
WinHelp (hFrameWnd, HelpEngineFile, HELP_INDEX, NULL);
}
else {
WinHelp (hFrameWnd, HelpEngineFile, HELP_KEY,
(DWORD)(LPSTR)&HelpKey[0]);
}
}
return TRUE;
} /* helpengine */
/* minimizescreen: turn the current screen into an icon */
/* ============== */
PASCAL minimizescreen (int f, int n)
{
BOOL nq;
nq = notquiescent;
notquiescent = 0;
ShowWindow (first_screen->s_drvhandle, SW_MINIMIZE);
notquiescent = nq;
return TRUE;
} /* minimizescreen */
/* ForceMessage: do a SendMessage, forcing quiescent mode */
/* ============ */
static PASCAL ForceMessage (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
{
BOOL nq;
nq = notquiescent;
notquiescent = 0;
SendMessage (hWnd, wMsg, wParam, lParam);
notquiescent = nq;
} /* ForceMessage */
/* maximizescreen: maximize the current screen */
/* ============== */
PASCAL maximizescreen (int f, int n)
{
ForceMessage (hMDIClientWnd, WM_MDIMAXIMIZE,
(UINT)first_screen->s_drvhandle, 0L);
return TRUE;
} /* maximizescreen */
/* restorescreen: restore the current screen from maximized/minimized state */
/* ============= */
PASCAL restorescreen (int f, int n)
{
ForceMessage (hMDIClientWnd, WM_MDIRESTORE,
(UINT)first_screen->s_drvhandle, 0L);
return TRUE;
} /* restorescreen */
/* tilescreens: tile the non-iconized screens */
/* =========== */
PASCAL tilescreens (int f, int n)
/* without a numeric argument, tile horizontally. With a numeric argument
of 1, tile vertically */
{
if (f && (n == 1)) {
ForceMessage (hMDIClientWnd, WM_MDITILE, MDITILE_HORIZONTAL, 0L);
}
else ForceMessage (hMDIClientWnd, WM_MDITILE, MDITILE_VERTICAL, 0L);
return TRUE;
} /* tilescreens */
/* cascadescreens: position the non-iconized screens in cascade */
/* ============== */
PASCAL cascadescreens (int f, int n)
{
ForceMessage (hMDIClientWnd, WM_MDICASCADE, 0, 0L);
return TRUE;
} /* cascadescreens */
/* renamescreen: change the current screen's name */
/* ============ */
PASCAL renamescreen (int f, int n)
{
char scr_name[NSTRING]; /* buffer to hold screen name */
int result;
/* get the new name of the screen */
if ((result = mlreply(TEXT335, scr_name, NSTRING)) != TRUE) {
/* "Change screen name to: " */
return result;
}
if (lookup_screen(scr_name) != (SCREEN*)NULL) {
mlwrite (TEXT336); /* "[Screen name already in use]" */
return FALSE;
}
free (first_screen->s_screen_name);
first_screen->s_screen_name = copystr (scr_name);
SetWindowText (first_screen->s_drvhandle, scr_name);
return TRUE;
} /* renamescreen */
/* ScrollMessage: handle WM_HSCROLL and WM_VSCROLL */
/* ============= */
void FAR PASCAL ScrollMessage (HWND hWnd, UINT wMsg, WORD ScrlCode, int Pos)
{
int Delta;
if (notquiescent) return;
if (wMsg == WM_VSCROLL) {
switch (ScrlCode) {
case SB_LINEUP:
mvupwind (FALSE, 1);
break;
case SB_LINEDOWN:
mvdnwind (FALSE, 1);
break;
case SB_PAGEUP:
backpage (FALSE, 1);
break;
case SB_PAGEDOWN:
forwpage (FALSE, 1);
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
if (Win31API) {
if (ScrlCode == SB_THUMBPOSITION) return;
}
else {
if (ScrlCode == SB_THUMBTRACK) return;
/* there is something wrong with thumb tracking in
Windows 3.0 */
}
Delta = Pos - GetScrollPos (hWnd, SB_VERT);
if (Delta) mvdnwind (TRUE, Delta);
break;
default:
return;
}
curwp->w_flag |= WFMODE;
}
else {
switch (ScrlCode) {
case SB_LINEUP:
Delta = -1;
break;
case SB_LINEDOWN:
Delta = 1;
break;
case SB_PAGEUP:
Delta = -term.t_ncol;
break;
case SB_PAGEDOWN:
Delta = term.t_ncol;
break;
case SB_THUMBTRACK:
Delta = Pos - GetScrollPos (hWnd, SB_HORZ);
break;
default:
return;
}
curwp->w_fcol += Delta;
if (curwp->w_fcol < 0) curwp->w_fcol = 0;
if (curwp->w_doto < curwp->w_fcol) {
/* reframe dot if it was left past the left of the screen */
curwp->w_doto = min(curwp->w_fcol,llength(curwp->w_dotp));
}
if (curwp->w_doto > (curwp->w_fcol + term.t_ncol - 2)) {
/* reframe dot if it was left past the right of the screen */
curwp->w_doto = curwp->w_fcol + term.t_ncol - 2;
}
curwp->w_flag |= WFMODE | WFHARD;
}
if (in_check()) GenerateMenuSeq (IDM_NULLPROC);
/* this ensures we go through the editloop(), updating the
modeline display and running the cmdhook, among other things */
ShowEmacsCaret (FALSE);
update (TRUE);
ShowEmacsCaret (TRUE);
} /* ScrollMessage */
/* ScrollBars: shows/hides, enables/disables scroll bars for all screens */
/* ========== */
void FAR PASCAL ScrollBars (void)
{
static int VScroll = TRUE;
static int HScroll = TRUE;
static int Enabled = TRUE;
int Quiescence;
SCREEN *sp;
if (vscrollbar) vscrollbar = TRUE; /* normalize... */
if (hscrollbar) hscrollbar = TRUE;
Quiescence = (notquiescent == 0);
for (sp = first_screen; sp != (SCREEN*)NULL; sp = sp->s_next_screen) {
if (vscrollbar != VScroll) {
ShowScrollBar ((HWND)sp->s_drvhandle, SB_VERT, vscrollbar);
}
if (hscrollbar != HScroll) {
ShowScrollBar ((HWND)sp->s_drvhandle, SB_HORZ, hscrollbar);
}
#if !WIN30SDK
#if !WINDOW_MSWIN32 /* ESB_ENABLE/DISABLE_BOTH not defined in
July 92 preliminary SDK for Windows NT */
if ((Enabled != Quiescence) && Win31API && !TakingANap) {
/* note: no disabling of scroll bars during naps (i.e. fence
matching), to avoid annoying blinking */
EnableScrollBar ((HWND)sp->s_drvhandle, SB_BOTH,
Quiescence ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH);
}
#endif
#endif
}
if ((Enabled != Quiescence) && Win31API && !TakingANap) {
Enabled = Quiescence;
}
VScroll = vscrollbar;
HScroll = hscrollbar;
} /* ScrollBars */
/* updscrollbars: updates the scroll bars for a screen */
/* ============= */
PASCAL updscrollbars (SCREEN *sp, char w_flag)
/* the w_flag is used to determine what needs updating: if the WFHARD
bit is set, both scroll bars need an update. If the WFMOVE bit
is set, the horizontal scroll bar needs an update */
/* this function assumes s_cur_window matches curwp for the first_screen */
{
int ScrollMax, ScrollMin, ScrollPos;
if (vscrollbar && (w_flag & WFHARD)) {
int lastline;
int topline;
{ /*-figure-out where we are at vertically */
register LINE *lp;
register LINE *linep; /* header (= last) line of buffer */
LINE *toplp; /* top line of window */
linep = sp->s_cur_window->w_bufp->b_linep;
toplp = sp->s_cur_window->w_linep;
topline = lastline = 0;
lp = linep;
do {
lp = lforw(lp);
lastline++;
if (lp == toplp) topline = lastline;
} while (lp != linep);
}
lastline += 1 - sp->s_cur_window->w_ntrows;
if (lastline <= 1) lastline = 2; /* to avoid scrollbar hiding */
lastline = min(lastline, MAXSCROLL);
topline = min(topline, MAXSCROLL);
GetScrollRange ((HWND)sp->s_drvhandle, SB_VERT,
&ScrollMin, &ScrollMax);
if ((ScrollMax != lastline) || (ScrollMin != 1)) {
SetScrollRange ((HWND)sp->s_drvhandle, SB_VERT, 1,
lastline, FALSE);
ScrollPos = -1; /* makes sure the scroll display is updated */
}
else ScrollPos = GetScrollPos ((HWND)sp->s_drvhandle, SB_VERT);
if (topline != ScrollPos) {
SetScrollPos ((HWND)sp->s_drvhandle, SB_VERT,
topline, TRUE);
}
}
if (hscrollbar && (w_flag & (WFMOVE | WFHARD))) {
/*-figure-out where we stand horizontally */
int row;
LINE *lp;
WINDOW *wp = sp->s_cur_window;
int maxlength = 0;
lp = wp->w_linep;
for (row = 0; (row < wp->w_ntrows) && (lp != wp->w_bufp->b_linep);
row++) {
maxlength = max(maxlength, llength(lp));
lp = lforw(lp);
}
if (maxlength <= 0) maxlength = 1;
maxlength = min(maxlength, MAXSCROLL);
row = min(wp->w_fcol, MAXSCROLL);
GetScrollRange ((HWND)sp->s_drvhandle, SB_HORZ,
&ScrollMin, &ScrollMax);
if ((ScrollMax != maxlength) || (ScrollMin != 0)) {
SetScrollRange ((HWND)sp->s_drvhandle, SB_HORZ, 0,
maxlength, FALSE);
ScrollPos = -1; /* makes sure the scroll display is updated */
}
else ScrollPos = GetScrollPos ((HWND)sp->s_drvhandle, SB_HORZ);
if (row != ScrollPos) {
SetScrollPos ((HWND)sp->s_drvhandle, SB_HORZ,
row, TRUE);
}
}
} /* updscrollbars */